package com.lnlyj.imagtext;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Paint;
import android.os.AsyncTask;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.DynamicDrawableSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;

import java.lang.ref.WeakReference;
import java.util.List;

import androidx.annotation.Nullable;

/**
 * wanglei 2020-02-22 11:22
 */
@SuppressLint("AppCompatCustomView")
public class ImageTextView extends TextView {

    private static final String TAG = "ImageTextView";

    public static final int IMAGE_SOURCE_HTTP = 1;
    public static final int IMAGE_SOURCE_SDCARD = 2;
    public static final int IMAGE_SOURCE_RESOURCE = 3;

    private int imageSource = IMAGE_SOURCE_SDCARD;
    private String imageText;
    private String path;

    private ImageDownloadTask task;

    public ImageTextView(Context context) {
        super(context);
    }

    public ImageTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ImageTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private static int getFontHeight(Paint paint) {
        Paint.FontMetricsInt fm = paint.getFontMetricsInt();
        //文字基准线的下部距离-文字基准线的上部距离 = 文字高度
        return fm.descent - fm.ascent;
    }

    public int getImageSource() {
        return imageSource;
    }

    public void setImageSource(int imageSource) {
        this.imageSource = imageSource;
    }

    public void setImageText(final String imageText) {

        this.imageText = imageText;

        if (task != null) {
            task.cancel(true);
            task = null;
        }

        task = new ImageDownloadTask(ImageTextView.this);

        task.setImageText(imageText);
        task.execute();
    }

    public String getImageText() {
        return imageText;
    }

    public String getPath() {
        return path == null ? "" : path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    private static class ImageDownloadTask extends AsyncTask<Void, Void, Void> {

        private WeakReference<ImageTextView> wr;
        private String imageText;
        private List<ImageBean> list;

        public ImageDownloadTask(ImageTextView textView) {
            this.wr = new WeakReference<>(textView);
        }

        @SuppressLint("WrongThread")
        @Override
        protected Void doInBackground(Void... voids) {

            list = HtmlUtils.filterImages(imageText);

            ImageTextView textView = wr.get();

            if (textView == null) {
                return null;
            }

            int replaceCount = 0;
            int i = 0;
            for (ImageBean bean : list) {

                if (textView.getImageSource() == IMAGE_SOURCE_SDCARD) {
                    bean.setDrawable(BitmapFactory.decodeFile(String.format("%s%s", textView.getPath(), bean.getPath())));
                } else if (textView.getImageSource() == IMAGE_SOURCE_RESOURCE) {
                    try {
                        bean.setDrawable(BitmapFactory.decodeResource(textView.getResources(), Integer.parseInt(bean.getPath())));
                    } catch (Exception e) {
                        Log.d(TAG, "parse int fail : ", e);
                        continue;
                    }
                } else {
                    // 网络
                    continue;
                }
                imageText = imageText.replace(bean.getSrc(), "d");
                bean.setStart(bean.getStart() - replaceCount + i);
                replaceCount += bean.getSrc().length();
                i++;
            }

            Log.d(TAG, "doInBackground: " + isCancelled());
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            final ImageTextView textView = wr.get();

            if (textView == null) {
                return;
            }

            textView.setText(imageText);

            textView.post(new Runnable() {
                @Override
                public void run() {

                    SpannableString span = new SpannableString(imageText);

                    for (ImageBean bean : list) {
                        if (isCancelled()) {
                            return;
                        }

                        if (bean.getDrawable() == null) {
                            continue;
                        }

                        CustomImageSpan image = new CustomImageSpan(textView.getContext(), bean.getDrawable(), DynamicDrawableSpan.ALIGN_BOTTOM);
                        image.setFontHeight(getFontHeight(textView.getPaint()));
                        image.setLineSpacingExtra(textView.getLineSpacingExtra());
                        image.setLineHeight(textView.getLineHeight());
                        image.setLineCount(textView.getLineCount());
                        span.setSpan(image, bean.getStart(), bean.getStart() + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }

                    if (isCancelled()) {
                        return;
                    }
                    textView.setText(span);
                    textView.setVisibility(VISIBLE);
                }
            });
        }

        public void setImageText(String imageText) {
            this.imageText = imageText;
        }
    }
}
